package nl.haemers.collections 
{
	import nl.haemers.collections.interfaces.ICollection;
	import nl.haemers.collections.interfaces.IIterator;
	import nl.haemers.collections.interfaces.IListIterator;
	
	import nl.haemers.collections.errors.NoSuchElementException;
	/**
	 * @author Jonathan Haemers
	 */
	public class AbstractSequentialList extends AbstractList
	{
		
		public function AbstractSequentialList() 
		{
			super();
		}
		
		/** Public methods **/
		/**
		 * @inheritDoc
		 */
		override public function addAt(location:int, e:Object) : void 
		{
			listIteratorAt(location).add(e);
		}
		
		/**
		 * @inheritDoc
		 */
		override public function addAllAt(location:int, collection:ICollection) : Boolean
		{
			var it:IListIterator = listIteratorAt(location);
			var collIt:IIterator = collection.iterator();
			
			var size:int  = this.size;
			while (collIt.hasNext())
			{
				it.add(collIt.next());
			}
			
			return size != this.size;
		}
		
		/**
		 * @inheritDoc
		 */
		override public function get(location:int) : Object 
		{
			try 
			{
				return listIteratorAt(location).next();
			}
			catch (e:NoSuchElementException)
			{
				throw new RangeError();
				//throw new IndexOutOfBoundsException();
			}
			return null;
		}
		
		/**
		 * @inheritDoc
		 */
		override public function iterator() : IIterator 
		{
			return listIterator();
		}
		
		override public function removeAt(location:int) : Object 
		{
			try 
			{
				var it:IListIterator = listIteratorAt(location);
				var result:Object = it.next();
				it.remove();
				
				return result;
			} 
			catch (e:NoSuchElementException) 
			{
				throw new RangeError("Location: " + location);
			}
			return null;
		}
		
		override public function set(location:int, e:Object) : Object 
		{
			var it:IListIterator = listIteratorAt(location);
			var result:Object = it.next();
			it.set(e);
			
			return result;
		}
		
		/** Abstract public methods **/
		//TODO: implement IListIterator.
		override public function listIteratorAt(location:int) : ListIterator 
		{
			return null;
		}
		/*

    @Override
    public E set(int location, E object) {
        ListIterator<E> it = listIterator(location);
        E result = it.next();
        it.set(object);
        return result;
    }
	*/
	}

}